import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.text.SimpleDateFormat;

public class Bridget {
	
	
	/* Db connection */
	Connection db;
	
	Professions professions;
	
	/* Business logic */
	private int     id;
	private String  name;
	private int     age;
	private int     factor1;
	private double  factor;
	private double  weight;
	private double  height;
	private boolean sex;
	private double  weightgoal;
	private double  fitgoal;
	private String  profession;
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
		saveName(name);
	}
	
	private void saveName(String name) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET name = '" + name + "' " +
						"WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
		saveAge(age);
	}
	
	private void saveAge(int age) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET age = " + (new Integer(age)).toString() +
						" WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getFactor() {
		return factor;
	}
	
	public void setFactor1(int value) {
		factor1 = value;
		saveFactor(value);
	}
	
	private void saveFactor(double value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				String s = "UPDATE users " +
				"SET factor = " + (new Double(value)).toString() +
				" WHERE id = " + (new Integer(id)).toString();
				System.out.println(s);
				st.executeUpdate(
					      "UPDATE users " +
					      "SET factor = " + (new Double(value)).toString() +
					      " WHERE id = " + (new Integer(id)).toString() + ";");  

			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getWeight() {
		return weight;
	}
	
	public void setWeight(double value) {
		weight = value;
		saveWeight(value);
	}
	
	private void saveWeight(double value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET weight = " + (new Double(value)).toString() +
						" WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getHeight() {
		return height;
	}
	
	public void setHeight(double value) {
		height = value;
		saveHeight(value);
	}
	
	private void saveHeight(double value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET height = " + ((new Double(value)).toString()) +
						" WHERE id = " + ((new Integer(id)).toString()));	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public boolean getSex() {
		return sex;
	}
	
	public void setSex(boolean value) {
		sex = value;
		saveSex(value);
	}
	
	private void saveSex(boolean value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET sex = " + ((new Boolean(value)).toString()) +
						" WHERE id = " + ((new Integer(id)).toString()));	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getWeightgoal() {
		return weightgoal;
	}
	
	public void setWeightgoal(double value) {
		weightgoal = value;
		saveWeightgoal(value);
	}
	
	private void saveWeightgoal(double value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET weightgoal = " + (new Double(value)).toString() +
						" WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getFitgoal() {
		return fitgoal;
	}
	
	public void setFitgoal(double value) {
		fitgoal = value;
		saveFitgoal(value);
	}
	
	private void saveFitgoal(double value) {
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET fitgoal = " + (new Double(value)).toString() +
						" WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public String getProfession() {
		return profession;
	}
	
	public void setProfession(String profession) {
		this.profession = profession;
		saveProfession(profession);
	}
	
	private void saveProfession(String profession) {
		
		int profid = professions.getIdByName(profession);
		
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				st.executeUpdate(
						"UPDATE users " +
						"SET profid = " + (new Double(profid)).toString() +
						" WHERE id = " + (new Integer(id)).toString());	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	public double getIdealWeight()
	{
		
	 double ideal;
	    if (sex)
	    {
	        ideal=(height-100)*0.85;
	    }
	    else
	    {
	        ideal=(height-100)*0.9;
	    }
	    /*(height-100-((height-150)/2));*/
	    return ideal;
    }
	
	
	public double getGoalEnergy()
	{
	    double energy;
	    if (sex)
	    {
	        double metabolism=655+9.56*getWeightgoal()+1.86*getHeight()-4.68*getAge();
	        energy=metabolism*getFactor();
	        System.out.println("factor!!"+getFactor());

	    }
	    else
	    {
	        double metabolism=66.5 +13.75*getWeightgoal() + 5*getHeight() - 6.78*getAge();
	        energy=metabolism*getFactor();

	    }
		energy = energy * 100;
		int i = (int) Math.round(energy);
		energy = (double)i / 100;
	    return energy;
	}
	
	public double getConsEnergy()
	{
		double energy=0;
		initDbConnection();
		Date date = new Date();
		if (db!=null)
		{
			try
			{
		    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		    String s= formatter.format(date);
		    System.out.println(s);
			Statement st = db.createStatement();
			ResultSet rs = st.executeQuery(
					"SELECT * FROM journal WHERE (userid="+(new Integer(id)).toString()	
			+") AND (dateadd='"+s+"')");
			
			while (rs.next())
			{
				double en = Double.parseDouble(rs.getString("energy").trim());
				if (en>0)
				{
					energy=energy+en;
				}
			}
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		energy = energy * 100;
		int i = (int) Math.round(energy);
		energy = (double)i / 100;
		return energy;
		
	}
	
	public double getSpendEnergy()
	{
		double energy=0;
		initDbConnection();
		Date date = new Date();
		if (db!=null)
		{
			try
			{
		    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		    String s= formatter.format(date);
		    System.out.println(s);
			Statement st = db.createStatement();
			ResultSet rs = st.executeQuery(
					"SELECT * FROM journal WHERE (userid="+(new Integer(id)).toString()	
			+") AND (dateadd='"+s+"')");
			
			while (rs.next())
			{
				double en = Double.parseDouble(rs.getString("energy").trim());
				if (en<0)
				{
					energy=energy+(-1)*en;
				}
			}
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		energy = energy * 100;
		int i = (int) Math.round(energy);
		energy = (double)i / 100;
		return energy;
	}
	
	
	
	
	public void toLogEat(double en, double weight1, String comment)
	{
		double energy = en*weight1*0.01;
		toLog(energy, comment);
		//initDbConnection();
		/*Date date = new Date();
		if (db!=null)
		{
			try
			{
		    
			Statement st = db.createStatement();
			ResultSet rs = st.executeQuery(
					"SELECT energy FROM product WHERE (name= '"+ name +"')");
			
			if (rs.next())
			{
				double en = Double.parseDouble(rs.getString("energy").trim());
				//weight in gr
				energy = en*weight1*0.01;
				toLog(energy);

			}
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}*/
		//return energy;
	}
	
	//(kkal/min*kg)
	public void toLogActivity(double en, double time, String comment)
	{
		//time in min
		double energy = (-1)*en*weight*time;
		toLog(energy, comment);
		//double energy=0;
	/*	initDbConnection();
		Date date = new Date();
		if (db!=null)
		{
			try
			{
		    
			Statement st = db.createStatement();
			ResultSet rs = st.executeQuery(
					"SELECT energy FROM activity WHERE (name= '"+ name +"')");
			
			if (rs.next())
			{
				double en = Double.parseDouble(rs.getString("energy").trim());
				//time in min
				energy = (-1)*en*weight*time;
				toLog(energy);

			}
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		return energy;*/
	}
	
	
	
	public void toLog(double energy, String comment)
	{
		energy = energy * 100;
		int i = (int) Math.round(energy);
		energy = (double)i / 100;

		initDbConnection();
		Date date = new Date();
		if (db!=null)
		{
			try
			{
			    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
				String s= formatter.format(date);
				Statement st = db.createStatement();
				st.executeUpdate(
					"INSERT INTO journal (dateadd, energy,userid,comment) "+
                      "VALUES ('"+s+"',"+(new Double(energy)).toString()+","+(new Integer(id)).toString()+
                               ",'" + comment + "')");
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}

	}
	
	public void setFactor(int factor1, double factor2)
	{
		System.out.println("In set");
		switch (factor1)
        {
                case 0:
                {
                	if (factor2>1.9)
                	{
                		factor=factor2;
                		
                	}
                	else
                	{
                		factor=1.9;
                	}
                                 break;
                }
                	

                case 1: 
                {
                	if (factor2>1.725)
                	{
                		factor=factor2+0.1;
                	}
                	else
                	{
                		factor=1.725;
                	}
                                 break;
                }

                case 2:  
                {
                	System.out.println("In set 2!!!!"+factor2);
                	if (factor2>1.55)
                	{
                		factor=factor2+0.05;
                	
                	}
                	else
                	{
                		factor=1.55;
                	}
                                 break;
                }
                case 3:  
                {
                	if (factor2>1.375)
                	{
                		factor=factor2;
                	}
                	else
                	{
                		factor=1.375+0.05;
                	}
                                 break;
                }
                case 4:
                {
                	factor=factor1;
                	break;
                }

                default: break;
        }
	}
	
	public ArrayList<JournalEntity> getLog() {
		ArrayList<JournalEntity> log = new ArrayList();
		
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				ResultSet rs = st.executeQuery(
						"select dateadd, comment, energy from journal where userid = " +
						(new Integer(id)).toString() + " order by dateadd;");
				while (rs.next()) {
					JournalEntity entity = new JournalEntity();
					entity.date = rs.getString("dateadd");
					entity.comment = rs.getString("comment");
					entity.energy = rs.getString("energy");
					log.add(entity);
					System.err.println("journal entity:" + entity.date + " " +
							entity.comment + " " + entity.energy);
				}	
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		return log;
		
	}
	
	
	
	private void initDbConnection() {
		try {
			Class.forName("org.postgresql.Driver");
		} catch (ClassNotFoundException e)
		{
			System.err.println("Class org.postgresql.Driver was not found: " 
					+ e.getMessage());
		}
		
		try {
		    db = DriverManager.getConnection(
		    		"jdbc:postgresql:dietsystem",
					"dietsystem",
					"dietsystem");
		} catch (SQLException e) {
			System.err.println(
					"Can't connect to \"jdbc:postgresql:dietsystem\":  "
					+ e.getMessage());
		}
	}

	/* Constructor */
	public Bridget() {
		
		initDbConnection();
		professions = new Professions();
		
		if (db != null)
		{
			try {
				Statement st = db.createStatement();
				ResultSet rs = st.executeQuery(
						"SELECT * FROM users");
				while (rs.next()) {
					id = Integer.parseInt(rs.getString("id").trim());
					name = rs.getString("name");
					age = Integer.parseInt(rs.getString("age").trim());
					factor1 = Integer.parseInt(rs.getString("factor").trim());
					weight = Double.parseDouble(rs.getString("weight").trim());
					height = Double.parseDouble(rs.getString("height").trim());
					sex = Boolean.parseBoolean(rs.getString("sex").trim());
					fitgoal = Double.parseDouble(rs.getString("fitgoal").trim());
					weightgoal = Double.parseDouble(rs.getString("weightgoal").trim());
					int profid = rs.getInt("profid");
					profession = professions.getNameById(profid);
					System.err.println(rs.getString(2));
					setFactor(factor1,professions.getFactor(profession));
					System.out.println(factor);
				}
				
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
	}
	
	public double getBMI()
	{
	    double t=getWeight()*10000/(getHeight()*getHeight());
	    return t;
	}

	public int statusBMI()
	{
	    int t;
	    if (getBMI()<16.5)
	    {
	        t=-2;
	    }
	    else
	        if (getBMI()<18.4)
	        {
	        t=-1;
	    }
	    else
	        if (getBMI()<24.9)
	        {
	        t=0;
	    }
	    else
	        if (getBMI()<30)
	    {
	        t=1;
	    }
	    else
	        if (getBMI()<34.9)
	        {
	        t=2;
	    }
	    else
	        if (getBMI()<40)
	        {
	        t=3;
	    }
	    else
	    {
	        t=4;
	    }
	    return t;

	}
	
	
	
	
	/* "Destructor" */
	protected void finalize() throws Throwable {
		try {
			db.close();
		} catch (SQLException e) {
			System.err.println(
					"Can't close connection to \"jdbc:postgresql:dietsystem\":  "
					+ e.getMessage());
		}
		finally {
			super.finalize();
		}
	}
	


}

class JournalEntity {
	public String date;
	public String comment;
	public String energy;
}
